package no.uib.hplims.views.search;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import no.uib.hplims.Controller;
import no.uib.hplims.MyVaadinApplication;
import no.uib.hplims.models.MyOrder;
import no.uib.hplims.models.Peptide;
import no.uib.hplims.tools.Icons;
import no.uib.hplims.tools.columngenerators.OrderColumnGenerator;
import no.uib.hplims.tools.columngenerators.UniProtAccessionColumnGenerator;
import no.uib.hplims.views.experiments.AddToExperimentWindow;
import no.uib.hplims.views.peptides.GeneralPeptideInformationView;

import org.vaadin.appfoundation.view.AbstractView;

import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.AbstractSelect.MultiSelectMode;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Table.ColumnGenerator;
import com.vaadin.ui.themes.Runo;

public class SearchResultsView extends AbstractView<VerticalLayout> implements
		Button.ClickListener {

	private static final long serialVersionUID = 5573168333447020555L;

	private VerticalLayout layout = null;

	private Table resultsTable = null;
	private Button addToExperimentButton = null;

	public SearchResultsView(String query, List<Peptide> results) {
		super(new VerticalLayout());
		layout = getContent();
		layout.setSpacing(true);
		layout.setMargin(true, true, true, true);

		setIcon(Icons.searchTabIcon16);

		setCaption("Search Results: " + query);

		Label header = new Label("Search Results");
		header.setStyleName(Runo.LABEL_H2);

		layout.addComponent(header);

		if (results.size() > 0) {
			// Add components to view
			layout.addComponent(new Label("Your search for \"" + query
					+ "\" returned " + results.size() + " result(s)."));
			layout.addComponent(createEditToolbar());

			ArrayList<Object> visibleColumnIds = new ArrayList<Object>();
			ArrayList<String> visibleColumnLabels = new ArrayList<String>();

			// Specify which columns are visible
			visibleColumnIds.add("belongsToOrder");
			visibleColumnIds.add("salesOrderCode");
			visibleColumnIds.add("wellID");
			visibleColumnIds.add("uniProtAccession");
			visibleColumnIds.add("peptideName");
			visibleColumnIds.add("numBlastHits");
			visibleColumnIds.add("peptideSequence");
			visibleColumnIds.add("sequenceLength");

			// Give those columns readable names
			visibleColumnLabels.add("Order");
			visibleColumnLabels.add("SO");
			visibleColumnLabels.add("Pos.");
			visibleColumnLabels.add("UniProt Acc. #");
			visibleColumnLabels.add("Peptidename");
			visibleColumnLabels.add("Blast hits");
			visibleColumnLabels.add("Sequence");
			visibleColumnLabels.add("Length");

			resultsTable = new Table();
			resultsTable.setSizeFull();

			// Enable/disable removeItemButton, depending on if there are items
			// selected
			resultsTable.addListener(new Property.ValueChangeListener() {
				private static final long serialVersionUID = 66492580135524046L;

				public void valueChange(ValueChangeEvent event) {
					Collection<?> items = (Collection<?>) event.getProperty()
							.getValue();
					addToExperimentButton.setEnabled(items.size() > 0);
				}
			});
			
			// Adding ItemClickListener to handle double clicks
						resultsTable.addListener(new ItemClickListener() {
							private static final long serialVersionUID = -9110150873687273692L;

							// Handle doubleClick
							public void itemClick(ItemClickEvent event) {
								if (event.isDoubleClick()) {
									if (event.getItemId() != null) {
										Peptide pojo = (Peptide) event.getItemId();

//										if (pojo != null) {
//											getWindow().addWindow(
//													new PeptideInformationWindow(
//															null,
//															getController(), pojo));
//										}

									}
								}

							}
						});

			// Set table properties
			resultsTable.setEditable(false);
			resultsTable.setMultiSelect(true);
			resultsTable.setMultiSelectMode(MultiSelectMode.DEFAULT);
			resultsTable.setSelectable(true);
			resultsTable.setImmediate(true);
			resultsTable.setWriteThrough(true);

			resultsTable.addGeneratedColumn("uniProtAccession",
					new UniProtAccessionColumnGenerator());

			resultsTable.addGeneratedColumn("belongsToOrder",
					new OrderColumnGenerator());

			resultsTable.addGeneratedColumn("salesOrderCode",
					new ColumnGenerator() {
						private static final long serialVersionUID = 2191917871103898427L;

						public Object generateCell(Table source, Object itemId,
								Object columnId) {
							final Peptide p = (Peptide) itemId;
							if (p.getBelongsToOrder() != null) {
								MyOrder o = p.getBelongsToOrder();
								return new Label(o.getSalesOrderCode());
							}
							return null;
						}
					});

			BeanItemContainer<Peptide> peptideContainer = new BeanItemContainer<Peptide>(
					Peptide.class);
			peptideContainer.addAll(results);

			resultsTable.setContainerDataSource(peptideContainer);

			// Customize table columns
			resultsTable.setVisibleColumns(visibleColumnIds.toArray());
			resultsTable.setColumnHeaders(visibleColumnLabels
					.toArray(new String[0]));

			// Add table to view
			layout.addComponent(resultsTable);
		} else {
			layout.addComponent(new Label("Your search for \"" + query
					+ "\" returned no results."));
		}

	}

	private Component createEditToolbar() {
		HorizontalLayout layout = new HorizontalLayout();
		layout.setSizeFull();

		final HorizontalLayout buttonLayout = new HorizontalLayout();

		addToExperimentButton = new Button("Add to experiment");
		addToExperimentButton.addListener(this);
		addToExperimentButton.setEnabled(false);
		buttonLayout.addComponent(addToExperimentButton);

		layout.addComponent(buttonLayout);

		return layout;
	}

	public void activated(Object... params) {
		// TODO Auto-generated method stub

	}

	public void deactivated(Object... params) {
		// TODO Auto-generated method stub

	}

	public void buttonClick(ClickEvent event) {
		if (event.getButton() == addToExperimentButton) {
			addToExperimentButtonClick();
		}

	}

	private void addToExperimentButtonClick() {
		if (resultsTable != null) {
			final Object selection = resultsTable.getValue();
			Collection<Peptide> selectionIndexes = null;
			if (selection == null) {
				return;
			}
			if (selection instanceof Peptide) {
				selectionIndexes = new ArrayList<Peptide>();
				selectionIndexes.add((Peptide) selection);
			} else if (selection instanceof Collection) {
				selectionIndexes = (Collection<Peptide>) selection;
			}

			if (selectionIndexes != null) {
				Window window = new AddToExperimentWindow(selectionIndexes);

				getWindow().addWindow(window);
			}
		}
	}
	
	private Controller getController() {
		return MyVaadinApplication.getInstance().getController();
	}

}
